﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace MISTBowl_Brackets
{
	public static class Combinations
	{

		public static List<List<T>> GetAllCombinations<T>(IEnumerable<T> input, int groupsize)
		{
			try
			{
				var output = new List<List<T>>();
				var indices = Enumerable.Range(0, groupsize).ToList();
				while (indices[0] < input.Count() - groupsize + 1)
				{
					output.Add(indices.ConvertAll(a => input.ElementAt(a)));
					indices[groupsize - 1]++;
					for (int i = groupsize - 1; i >= 0; i--)
					{
						if (indices[i] >= input.Count() - groupsize + i + 1)
						{
							indices[i] = i > 0 ? ++indices[i - 1] + 1 : indices[i] + 1;
							for (int j = i + 1; j < groupsize; j++)
								indices[j] = indices[i] + j - i;
						}
					}
				}
				return output;
			}
			catch (Exception e)
			{
				Traceback.Write("At List<List<T>> GetAllCombinations<T>(IEnumerable<T>, int) (class Combinations):");
				throw e;
			}
		}

		public static List<List<Team>> GenerateBestMatches(List<Team> teams, int teamsPerMatch, int matchCount, List<Team> origTeamList)
		{
			if (teamsPerMatch * matchCount > teams.LongCount())
				throw new ArgumentOutOfRangeException();
			var combinations = GetAllCombinations(teams, teamsPerMatch).OrderBy(a => a.SameRegionMatchCount()).ThenBy(a => a.RepeatMatchCount()).ThenBy(a => a.RepeatRegionMatchCount(origTeamList)).ThenBy(a => TickBasedRandom.GetInteger(int.MinValue, int.MaxValue - 1)).ToList();
			var matches = new List<List<Team>>();
			while (matches.Count < matchCount)
			{
				if (!combinations[0].Any(a => matches.Any(b => b.Any(c => c.teamId == a.teamId))))
					matches.Add(combinations[0]);
				combinations.RemoveAt(0);
			}
			return matches;
		}
	}
}